<?php

namespace App\Process;


use App\Logic\ActivityLogic;
use App\Model\ActivityApplyModel;
use App\Model\ActivityModel;
use App\Model\UserModel;
use App\Model\VestQueueModel;
use App\Utility\CommonTool;
use co;
use EasySwoole\Component\Process\AbstractProcess;
use EasySwoole\EasySwoole\Logger;
use EasySwoole\ORM\DbManager;
use EasySwoole\Pool\Manager;
use Swoole\Process;
use Throwable;

/**
 * Class VirtualMultiSignProcess
 * 虚拟用户队列出列加入活动赛事中
 * @package App\Process
 */
class VirtualQueuePopProcess extends AbstractProcess
{
    protected function run($arg)
    {
        //当进程启动后，会执行的回调
        Logger::getInstance()->info($this->getProcessName() . " run");
        var_dump($arg);

        go(function () {
            while (true) {
                $queue = DbManager::getInstance()->invoke(function ($client) {
                    $info = VestQueueModel::invoke($client)
                        ->where('is_done', 2)
                        ->where('job_time', time(), '<=')
                        ->order('job_time', 'asc')
                        ->limit(1)
                        ->get();
                    if ($info) {
                        $info->is_done = 3;
                        $info->update();
                        return $info;
                    } else {
                        return [];
                    }
                });

                if ($queue) {
                    go(function () use ($queue) {
                        // 获取赛事信息
                        $activity = DbManager::getInstance()->invoke(function ($client) use ($queue) {
                            return ActivityModel::invoke($client)
                                ->where('id', $queue->activity_id)
                                ->where('status', 1)
                                ->get();
                        });
                        if (!$activity) {
                            return false;
                        }

                        // 随机抽取虚拟用户
                        $randUser = DbManager::getInstance()->invoke(function ($client) use ($queue, $activity) {
                            if ($activity->is_add != 1) {
                                $applyUserIds = [];
                                $redis = Manager::getInstance()->get('redis')->getObj();
                                if ($redis->exists('set_join_' . $queue->activity_id)) {
                                    $applyUserIds = $redis->sMembers('set_join_' . $queue->activity_id);
                                }
                                Manager::getInstance()->get('redis')->recycleObj($redis);
                            } else {
                                $applyUserIds = [];
                            }

                            $userModel = UserModel::invoke($client);
                            $tmpObj = $userModel->field(['(((MAX(`id`)-MIN(`id`)) * RAND()) + MIN(`id`)) AS rand_id'])->where('is_real', 2)->get();

                            $userModel->where('id', $tmpObj->rand_id, '>=')->where('is_real', 2)->limit($queue->vest_enrollment);
                            if (count($applyUserIds) > 0) {
                                $userModel->where('id', $applyUserIds, 'not in');
                            }

                            return $userModel->field(['id'])->all();
                        });

                        if (count($randUser) <= 0) {
                            return false;
                        }

                        mt_srand();

                        // 加入赛事
                        foreach ($randUser as $v) {
                            if ($activity->is_add == 1) {
                                $consumeMaps = CommonTool::getAllConsumeMap();
                                $key = array_rand($consumeMaps, 1);
                                $odds = $consumeMaps[$key]['multiple'];
                            } else {
                                $odds = 1;
                            }

                            // 间隔随机1~5秒
                            co::sleep(mt_rand(1, 5));
                            $res = ActivityLogic::joinActivity($v->id, $queue->activity_id, 0, intval($activity->bet_amount * $odds), 2);
                            Logger::getInstance()->info("当前添加虚拟用户的赛事是" . $queue->activity_id . ",添加的用户ID是" . $v->id . ",添加的倍数是" . $odds . ",添加的金额是" . intval($activity->bet_amount * $odds) . ",当前虚拟用户参加赛事结果是" . json_encode($res));
                        }

                        $queue->destroy();
                        return true;
                    });

                    return true;
                }

                co::sleep(1);
            }

            return true;
        });
    }

    protected function onPipeReadable(Process $process)
    {
        /*
         * 该回调可选
         * 当有主进程对子进程发送消息的时候，会触发的回调，触发后，务必使用
         * $process->read()来读取消息
         */
    }

    protected function onShutDown()
    {
        /*
         * 该回调可选
         * 当该进程退出的时候，会执行该回调
         */
    }

    protected function onException(Throwable $throwable, ...$args)
    {
        /*
         * 该回调可选
         * 当该进程出现异常的时候，会执行该回调
         */
        echo $throwable->getMessage();
    }
}
